from dao.picture import PictureDao
from dao.category import CategoryDao

from werkzeug.utils import secure_filename

from cfg import cfg

import shutil    
import os


def make_dirs(_path):
    """Arguments:
    path -- the relative path to current path
    Example: './l1/l2' or 'l1/l2'
    """
    if not os.path.exists(_path):
        os.makedirs(_path)
        return True
    return False

def remove_dirs(_path):
    if os.path.isdir(_path):
        shutil.rmtree(_path)

def get_dirs(fpath):
    """Get parent dirs
    """
    return os.path.dirname(fpath)
    
def create_file(fpath):
    if not os.path.exists(fpath):
        f = open(fpath, 'w')
        f.close()
        return True
    return False
    
def remove_file(fpath):
    """ If file exists and is a file
    """
    if os.path.isfile(fpath):
        os.remove(fpath)


class PictureService():
    def __init__(self, username, category_name, item_id):
        """Arguments:
            username -- string type
            category_name -- string type
            item_id -- BSON ObjectId type
        """
        self.username = username
        self.item_id = str(item_id)
        self.category_name = category_name
        
        self.base_path = cfg.picture_base
        self.path = r'{0}/{1}/{2}/{3}'.format(self.base_path, username, category_name, item_id)
        self.builtin_path = r'{0}/builtin/{1}/{1}.jpg'.format(self.base_path, category_name) 
        self.dao = PictureDao()
    
    def get_picture_path(self, fname):
        """ If file name is not None, return full path, otherwise return build in picture path
        """
        if self.exist(fname):
            return r'./{0}/{1}'.format(self.path, fname)
        else:
            return r'./{0}/built_in/{1}/default.jpg'.format(self.base_path, self.category_name)
            
    def get_all_pictures(self):
        return os.listdir(r'./{0}'.format(self.path))
        
    def create_picture_folders(self):
        ''' Create a picture folder for item if not exist, the path is ./datas/images/u+user_id/i+item_id
        Arguments:
            item --- Item model object
        '''
        # The upload path is relative to the app root
        
        return make_dirs(r'./' + self.path)

    def exist(self, fname):
        """Arguments:
            fname -- file name
        """
        if fname is None:
            return False
        else:
            fpath = r'./' + self.path + r'/' + fname
            return os.path.exists(fpath) and os.path.isfile(fpath)
        #return ret is not None
    
    def upload(self, _file):
        '''Upload single file to the server, if file exist overwrite it, otherwise create folders and file.
        Arguments:
        _file -- form.request.files object
        '''
        fname = secure_filename(_file.filename)

        # Check if file is in database already
        fpath = self.path + r'/' + fname
        if self.exist(r'./' + fpath):
            remove_file( r'./' + fpath)
            _file.save( r'./' + fpath)
        else:
            if not self.exist(r'./' + self.path):
                self.create_picture_folders()
            _file.save( r'./' + fpath)

    def update(self, _file, old_fname):
        """Arguments:
            old_fname -- The file name to be replaced, could be None
        """
        if old_fname is not None:
            remove_file( r'./' + self.path + r'/' +secure_filename(old_fname))
        self.upload(_file)

    def delete_picture(self, picture, del_record=False):
        '''Delete picture from the disk, use a default picture
        Arguments:
        picture -- The model class of Picture or the dict type
        '''
        ret_picture = None
        if isinstance(picture,dict):
            ret_picture = self.dao.find_one({'_id': picture['_id']})
        else:
            ret_picture = self.dao.find_one({'_id': picture._id})
        
        if ret_picture.fname is not None:            
            fpath = r'./' + self.path + '/' + ret_picture.fname
            remove_file(fpath)
        
        if del_record:
            self.dao.remove(ret_picture)
        else:# set a default picture
            ret_picture.fname = None
            self.dao.save(ret_picture)
        #pictures = self.dao.find({'item.$id': self.item._id})
        
        
    def delete_pictures(self):
        """Delete all the pictures under the folder
        """
        _path = r'./' + self.path
        shutil.rmtree(_path)
        #self.dao.delete(item_id = item.id)

    def save_picture(self, picture, mode=None):
        ''' Could be add new picture or update picture
        Arguments:
            picutre --- The Picture model object
            _file --- The file object from the request
            item --- The Item model object
        '''
        # Save file info to database
        if mode is None:
            self.dao.save(picture)

    
if __name__ == "__main__":
    #run()
    _path = 'hello/hello1'
    fname = 'pic.jpg'
    fpath = os.path.join(_path, fname)
    make_dirs('hello/hello1')
    create_file(fpath)
    remove_file(fpath)
    remove_dirs('hello')
